///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file configuration.cpp
///
/// \brief   implementation of members for the Configuration and ConfigDiff classes
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#include<src/pcps.h>
#include<src/configuration.h>

///////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief  constructor from two configurations
///
/// \param[in]      new_config     the new configuration
/// \param[in]      old_config     the old configuration
///
///////////////////////////////////////////////////////////////////////////////////////////////////
template <class S> pcps::ConfigDiff<S>::ConfigDiff(const pcps::Configuration<S> & new_config, const pcps::Configuration<S> & old_config)
  : _newly_empty(),
    _newly_full()
    //_noise_change_codes(2, 'n'),
    //_noise_changes(2)
{

  // ensure the fock vectors are the same lengths
  if ( new_config.fock_config().size() != old_config.fock_config().size() )
    throw pcps::Exception("fock vector size mismatch in ConfgDiff constructor");

  // process alpha and beta sites separately
  for (int b = 0; b < 2; b++) {

    // check for sites for which the occupation changed
    for (int i = b; i < new_config.fock_config().size(); i+=2)
      if (new_config.fock_config()[i] == 0 && old_config.fock_config()[i] == 1)
        _newly_empty.push_back(i);
      else if (new_config.fock_config()[i] == 1 && old_config.fock_config()[i] == 0)
        _newly_full.push_back(i);

    // ensure there were the same number of particles created as destroyed
    if ( _newly_empty.size() != _newly_full.size() )
      throw pcps::Exception("uneven number of newly empty/full sites for %s particles in ConfgDiff constructor")
            % ( b == 0 ? "alpha" : "beta" );

  }

}

template pcps::ConfigDiff<double>::ConfigDiff(const pcps::Configuration<double> & new_config,
                                         const pcps::Configuration<double> & old_config);
template pcps::ConfigDiff<std::complex<double> >::ConfigDiff(const pcps::Configuration<std::complex<double> > & new_config,
                                                             const pcps::Configuration<std::complex<double> > & old_config);
